import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { CacheService } from '../cache/cache.service';
import * as SMS from 'tencentcloud-sdk-nodejs-sms';
import { SendSmsDto } from './dto/send-sms.dto';
import { ApiException } from '../common/filter/http-exception/api.exception';
import { ApiErrorCode } from '../common/enums/api-error-code.enum';

@Injectable()
export class SmsService {
  constructor(private cacheService: CacheService) {}

  /**
   * 创建短信客户端
   */
  smsClient() {
    const SmsClient = SMS.sms.v20210111.Client;
    const clientConfig = {
      credential: {
        secretId: process.env.TENCENT_SECRET_ID,
        secretKey: process.env.TENCENT_SECRET_KEY,
      },
      region: 'ap-guangzhou',
      profile: {
        httpProfile: {
          endpoint: 'sms.tencentcloudapi.com',
        },
      },
    };
    return new SmsClient(clientConfig);
  }

  /**
   * 发送短信验证码
   * @param sendSmsDto
   */
  async send(sendSmsDto: SendSmsDto) {
    // 生成6位数字验证码
    const code = (Math.floor(Math.random() * 900000) + 100000).toString();
    for (const mobile of sendSmsDto.mobile) {
      const mobileValidate = /^(?:(?:\+|00)86)?1[3-9]\d{9}$/.test(mobile);
      if (!mobileValidate)
        throw new ApiException('请输入正确的手机号码', ApiErrorCode.SMS_ERROR);
      const sendFrequency = await this.cacheService.get(
        `验证码频率验证：${mobile}`,
      );
      if (sendFrequency)
        throw new ApiException(
          '验证码发送频率过快，请1分钟后再试',
          ApiErrorCode.SMS_ERROR,
        );
      // 将验证码存入redis
      await this.cacheService.set(`验证码：${mobile}`, code, 600);
      await this.cacheService.set(`验证码频率验证：${mobile}`, 1, 60);
    }
    const params = {
      PhoneNumberSet: sendSmsDto.mobile,
      SmsSdkAppId: '1400673034',
      SignName: '上海速巨',
      TemplateId: '2113514',
      TemplateParamSet: [code, '10'],
    };
    try {
      await this.smsClient().SendSms(params);
      return '发送成功';
    } catch (error) {
      throw new HttpException(error, HttpStatus.INTERNAL_SERVER_ERROR);
    }
  }

  /**
   * 验证短信验证码
   * @param mobile
   * @param code
   */
  async verify(mobile: string, code: string) {
    const cacheCode = await this.cacheService.get(`验证码：${mobile}`);
    if (!cacheCode) return false;
    return cacheCode === code;
  }
}
